/* $Id$ */
#ifndef LIST_INCLUDED
#define LIST_INCLUDED
#define T List_T
typedef struct T *T;
struct T
{
    T rest;
    void *first;
};

/**
 * @brief add tail to the tail of list
 *
 * @param list the list to be appended
 * @param tail tail element
 * @return T
 */
extern T List_append(T list, T tail);
extern T List_copy(T list);

/**
 * @brief create and return a list
 *
 * @param x
 * @param ...
 * @return T
 */
extern T List_list(void *x, ...);

/**
 * @brief delet the first node of list, and return the first node
 *
 * @param list list to be pop
 * @param x  first node of list
 * @return T list after pop
 */
extern T List_pop(T list, void **x);

extern T List_push(T list, void *x);
extern T List_reverse(T list);
extern int List_length(T list);
extern void List_free(T *list);

/**
 * @brief traverse list and apply function to every node
 *
 * @param list
 * @param apply function point
 * @param cl    function parameter
 */
extern void List_map(T list,
                     void apply(void **x, void *cl),
                     void *cl);

/**
 * @brief create an Array to store list
 * Array length = n+1, List length = n;
 * @param list
 * @param end   a node at the end of Array
 * @return void**
 */
extern void **List_toArray(T list, void *end);
#undef T
#endif